<template>
  <el-dialog
      v-model="computedDialogVisible"
      :title="dialogTitle"
      width="1000"
      @close="handleClose"
  >
    <el-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        label-position="right"
        label-width="auto"
    >
      <el-form-item label="模板名称" prop="name">
        <el-input v-model="formData.name" placeholder="请输入模板名称" />
      </el-form-item>
      <el-form-item label="计费方式" prop="type">
        <el-radio-group v-model="formData.type">
          <el-radio :value="0">按件数</el-radio>
          <el-radio :value="1">按重量</el-radio>
          <el-radio :value="2">按体积</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="配送区域及运费" prop="rules">
        <el-table :data="formData.rules" style="width: 100%">
          <el-table-column align="center" label="可配送区域" width="120">
            <template #default="scope">
              <el-button
                  size="small"
                  @click="handleEditArea(scope.$index)"
                  icon="Edit"
                  type="primary"
                  link
              >
                编辑
              </el-button>
            </template>
          </el-table-column>
          <el-table-column align="left" :label="firstLabel">
            <template #default="scope">
              <el-input-number
                  :min="0"
                  size="small"
                  v-model="scope.row.first"
                  controls-position="right"
              />
            </template>
          </el-table-column>
          <el-table-column align="left" label="运费(元)">
            <template #default="scope">
              <el-input-number
                  :min="0"
                  :precision="2"
                  size="small"
                  v-model.number="scope.row.first_fee"
                  controls-position="right"
              />
            </template>
          </el-table-column>
          <el-table-column align="left" :label="continueLabel">
            <template #default="scope">
              <el-input-number
                  :min="0"
                  size="small"
                  v-model="scope.row.continue"
                  controls-position="right"
              />
            </template>
          </el-table-column>
          <el-table-column align="left" label="续费(元)">
            <template #default="scope">
              <el-input-number
                  :min="0"
                  :precision="2"
                  size="small"
                  v-model.number="scope.row.continue_fee"
                  controls-position="right"
              />
            </template>
          </el-table-column>
          <el-table-column align="left" label="操作" width="100">
            <template #default="scope">
              <el-button
                  type="danger"
                  link
                  @click="handleDelArea(scope.$index)"
                  icon="Delete"
              >
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-button class="mt-2.5" type="primary" @click="handleAddArea">
          <el-icon class="mr-1"><Plus /></el-icon>添加配送区域
        </el-button>
      </el-form-item>
      <el-form-item label="排序" prop="sort">
        <el-input-number :min="0" v-model="formData.sort" />
      </el-form-item>
    </el-form>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleSubmit">
          {{ submitText }}
        </el-button>
      </div>
    </template>

    <!-- 地区选择弹窗 -->
    <el-dialog
        v-model="areaShow"
        :title="editingRuleIndex === null ? '添加配送区域' : '编辑配送区域'"
        @close="handleAreaClose"
        width="800"
    >
      <div class="mb-4">
        <el-checkbox
            v-model="selectAllChecked"
            :indeterminate="isIndeterminate"
            @change="handleSelectAll"
        >
          <el-text type="primary">{{ selectAllText }}</el-text>
        </el-checkbox>
        <div class="selected-info mt-2">
          已选择: <span class="selected-count">{{ selectedAreaCount }}</span> 个地区
        </div>
      </div>

      <div class="region-container">
        <el-row :gutter="20">
          <el-col
              v-for="item in regionList"
              :key="item.area_code"
              :span="6"
          >
            <div class="province-item">
              <el-checkbox
                  :model-value="isProvinceSelected(item)"
                  :indeterminate="isProvinceIndeterminate(item)"
                  @change="toggleProvinceSelection(item)"
              >
                {{ item.name }}
                <span class="selected-count">
                  ({{ getSelectedCount(item) }})
                </span>
              </el-checkbox>

              <div class="city-container">
                <el-checkbox
                    v-for="child in item.children"
                    :key="child.area_code"
                    v-model="areaIds"
                    :label="child.area_code"
                    class="city-checkbox"
                >
                  {{ child.name }}
                </el-checkbox>
              </div>
            </div>
          </el-col>
        </el-row>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="handleAreaClose">取消</el-button>
          <el-button type="primary" @click="submitSelectArea">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, watch, computed } from 'vue'
import { ElMessage, FormInstance, FormRules, ElMessageBox } from "element-plus"
import { Plus } from '@element-plus/icons-vue'
import {getTreeAreaListApi} from "@/api/region";
import {
  getShippingTemplateInfoApi,
  saveShippingTemplateInfoApi,
  updateShippingTemplateInfoApi
} from "@/api/shippingTemplate";

interface ShippingRule {
  region_ids: string[]
  first: number
  first_fee: number
  continue: number
  continue_fee: number
}

interface FormDataTypes {
  id?: number
  name: string
  type: number
  sort: number
  rules: ShippingRule[]
}

interface Region {
  area_code: string
  name: string
  children?: Region[]
}

const props = defineProps({
  modelValue: Boolean,
  mode: {
    type: String,
    validator: (v: string) => ['create', 'edit'].includes(v),
    default: 'create'
  },
  editId: [String, Number]
})

const emit = defineEmits(['update:modelValue', 'success'])

const formRef = ref<FormInstance>()
const formData = ref<FormDataTypes>(initForm())
const areaShow = ref(false)
const areaIds = ref<string[]>([])
const regionList = ref<Region[]>([])
const selectAllChecked = ref(false)
const isIndeterminate = ref(false)
const areaMap = ref<Record<string, string>>({})
const editingRuleIndex = ref<number | null>(null)

// 初始化表单数据
function initForm() {
  return {
    name: '',
    type: 0,
    sort: 0,
    rules: []
  }
}

// 计算属性
const isEditMode = computed(() => props.mode === 'edit')
const dialogTitle = computed(() => isEditMode.value ? '编辑运费模板' : '新建运费模板')
const submitText = computed(() => isEditMode.value ? '保存修改' : '立即创建')
const selectAllText = computed(() => selectAllChecked.value ? '取消全选' : '全选')
const selectedAreaCount = computed(() => areaIds.value.length)
const computedDialogVisible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})
const firstLabel = computed(() => formData.value.type === 0 ? '首件(个)' : '首重(kg)')
const continueLabel = computed(() => formData.value.type === 0 ? '续件(个)' : '续重(kg)')

// 表单验证规则
const rules = ref<FormRules>({
  name: [
    { required: true, message: '模板名称不能为空', trigger: 'blur' },
    { min: 2, max: 20, message: '模板名称长度在2到20个字符', trigger: 'blur' }
  ],
  type: [
    { required: true, message: '请选择计费方式', trigger: 'change' }
  ],
  rules: [
    {
      validator: (_, value, callback) => {
        if (value.length === 0) {
          callback(new Error('请至少添加一个配送区域'))
        } else {
          callback()
        }
      },
      trigger: 'change'
    }
  ],
  sort: [
    { type: 'number', min: 0, max: 999, message: '排序值应在0-999之间', trigger: 'blur' }
  ]
})

// 省份选择状态
const isProvinceSelected = (province: Region) => {
  const childCodes = province.children?.map((c: any) => c.area_code) || []
  if (childCodes.length === 0) return false
  return childCodes.every(code => areaIds.value.includes(code))
}

const isProvinceIndeterminate = (province: Region) => {
  const childCodes = province.children?.map((c: any) => c.area_code) || []
  if (childCodes.length === 0) return false

  const hasSelected = childCodes.some(code => areaIds.value.includes(code))
  return hasSelected && !isProvinceSelected(province)
}

// 方法定义
const toggleProvinceSelection = (province: Region) => {
  const childCodes = province.children?.map((c: any) => c.area_code) || []
  if (childCodes.length === 0) return

  const currentSelected = isProvinceSelected(province)
  let newAreaIds = [...areaIds.value]

  if (currentSelected) {
    newAreaIds = newAreaIds.filter(code => !childCodes.includes(code))
  } else {
    const newSet = new Set([...newAreaIds, ...childCodes])
    newAreaIds = Array.from(newSet)
  }

  areaIds.value = newAreaIds
}

const getSelectedCount = (province: Region) => {
  if (!province.children) return 0
  return province.children.filter((child: any) =>
      areaIds.value.includes(child.area_code)
  ).length
}

const formatAreaNames = (areaCodes: string[]) => {
  return areaCodes
      .map(code => areaMap.value[code] || code)
      .join('、')
}

const handleClose = () => {
  emit('update:modelValue', false)
}

const handleAddArea = () => {
  editingRuleIndex.value = null
  areaIds.value = []
  areaShow.value = true
  if (regionList.value.length === 0) {
    getRegionList()
  }
}

const handleEditArea = (index: number) => {
  editingRuleIndex.value = index
  areaIds.value = [...formData.value.rules[index].region_ids]
  areaShow.value = true
  if (regionList.value.length === 0) {
    getRegionList()
  }
}

const handleDelArea = (index: number) => {
  ElMessageBox.confirm('确定删除该配送区域吗？', '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    formData.value.rules.splice(index, 1)
    ElMessage.success('删除成功')
  }).catch(() => {})
}

const handleAreaClose = () => {
  areaIds.value = []
  areaShow.value = false
  editingRuleIndex.value = null
}

const buildAreaMap = (areas: Region[]) => {
  areas.forEach(area => {
    areaMap.value[area.area_code] = area.name
    if (area.children?.length) {
      buildAreaMap(area.children)
    }
  })
}

const getRegionList = async () => {
  const { data } = await getTreeAreaListApi({});
  regionList.value = data;

  // 构建地区映射表
  buildAreaMap(data);
}

const submitSelectArea = () => {
  if (areaIds.value.length === 0) {
    ElMessage.error('请选择配送区域')
    return
  }

  // 检查所选地区是否已被其他规则使用
  const allUsedAreaIds = formData.value.rules.flatMap(rule => rule.region_ids)
  const isDuplicate = areaIds.value.some(id =>
      allUsedAreaIds.includes(id) &&
      (editingRuleIndex.value === null ||
          !formData.value.rules[editingRuleIndex.value].region_ids.includes(id))
  )

  if (isDuplicate) {
    ElMessage.error('所选地区已在其他规则中使用')
    return
  }

  if (editingRuleIndex.value !== null) {
    // 更新现有规则
    formData.value.rules[editingRuleIndex.value].region_ids = [...areaIds.value]
  } else {
    // 添加新规则
    formData.value.rules.push({
      region_ids: [...areaIds.value],
      first: 1,
      first_fee: 0,
      continue: 1,
      continue_fee: 0
    })
  }

  areaShow.value = false
  areaIds.value = []
  editingRuleIndex.value = null
}

const handleSubmit = async () => {
  if (!formRef.value) return;

  try {
    // 校验表单
    await formRef.value.validate();

    // 判断是否为新增或更新
    const isUpdate = !!formData.value.id;

    // 执行新增或更新操作
    if (isUpdate) {
      // 更新操作
      await updateShippingTemplateInfoApi(formData.value.id, formData.value);
      ElMessage.success('更新成功');
    } else {
      // 新增操作
      await saveShippingTemplateInfoApi(formData.value);
      ElMessage.success('新增成功');
    }

    handleClose();
    emit('success');
  } catch (error) {
    console.log('表单验证失败', error);
  }
};

const loadTemplateData = async (id: string | number) => {
  try {
    const { data } = await getShippingTemplateInfoApi(id)
    formData.value = { ...data }

    if (Object.keys(areaMap.value).length === 0) {
      await getRegionList()
    }
  } catch (e) {
    handleClose()
    ElMessage.error('数据加载失败')
  }
}

const resetForm = () => {
  formData.value = initForm()
}

// 监管模式变化
watch(
    () => props.mode,
    (newVal) => {
      if (newVal === 'create') resetForm()
    }
)

// 数据加载
watch(
    () => props.editId,
    async (newVal) => {
      if (isEditMode.value && newVal) {
        await loadTemplateData(newVal)
      }
    },
    { immediate: true }
)

watch(areaIds, (newVal) => {
  const totalAreas = Object.keys(areaMap.value).length
  if (newVal.length === 0) {
    selectAllChecked.value = false
    isIndeterminate.value = false
  } else if (newVal.length === totalAreas) {
    selectAllChecked.value = true
    isIndeterminate.value = false
  } else {
    selectAllChecked.value = false
    isIndeterminate.value = true
  }
})

const handleSelectAll = (checked: boolean) => {
  if (checked) {
    areaIds.value = Object.keys(areaMap.value)
  } else {
    areaIds.value = []
  }
}
</script>

<style scoped>
.province-item {
  display: flex;
  flex-direction: column;
  padding: 12px;
  margin-bottom: 10px;
  border-radius: 6px;
  background: #f8fafc;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
}

.province-item:hover {
  background: #f1f5f9;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.city-container {
  display: flex;
  flex-wrap: wrap;
  margin-top: 8px;
  padding-left: 24px;
}

.city-checkbox {
  width: 100px;
  margin: 4px 0;
}

.selected-info {
  padding: 10px 15px;
  background: #e6f7ff;
  border-radius: 4px;
  font-size: 14px;
}

.selected-count {
  font-weight: bold;
  color: var(--el-color-primary);
  margin: 0 3px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 20px;
}

.mt-2\.5 {
  margin-top: 10px;
}

.region-container {
  max-height: 50vh;
  overflow-y: auto;
  padding-right: 8px;
}

.el-col {
  margin-bottom: 10px;
}
</style>